package com.docker.manege.log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.docker.core.mvc.service.BaseService;
import com.docker.manege.server.DockerServerDao;
import com.docker.manege.server.DockerServerService;
import com.jfinal.aop.Inject;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.Okv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Record;
import kit.docker.datetime.DateKit;
import kit.docker.exception.BaseException;
import kit.docker.security.MD5Kit;
import kit.docker.web.RequestKit;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wangbei
 * @date 2020/12/4 - 10:39
 */
public class LoggerService extends BaseService {

    @Inject
    private DockerServerDao dockerServerDao;

    @Inject
    private DockerServerService dockerServerService;

    private final String START_LINE = "1";

    private final String STATUS_OK = "200";

    public String filelist(String serverId, String basePath, String filePath) {
        Map<String, String> param = new HashMap<>();
        param.put("base_path", basePath);
        param.put("file_path", StrKit.isBlank(filePath) ? "" : filePath);
       return post(getUrl(serverId, "/api/log/manege/files"), param);
    }

    private String getUrl(String serverId, String api) {
        Record server = dockerServerService.info(serverId);
        String loggerServerPort = server.getStr("logger_server_port");
        if (StrKit.isBlank(loggerServerPort)) {
            throwError("未配置日志端口");
        }
        return "http://" + server.getStr("docker_host") + ":" + loggerServerPort + api;
//        return "http://192.168.1.110:8081" + api;
    }

    public Object readLastLines(String serverId, String basePath, String filePath, String charset, String readLine, String startLine) {
        if (!startLine.equals(START_LINE)) {
            return readLines(serverId, basePath, filePath, charset, startLine, readLine);
        }
        try {
            String data = post(getUrl(serverId, "/api/log/manege/read/last/lines"),
                    getParaMap(basePath, filePath, charset, startLine, readLine));
            List<Okv> collect = getReadLineResult(data);
            return JSON.toJSON(collect);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private Map<String, String> getParaMap(String basePath, String filePath, String charset, String startLine, String readLine) {
        String OS = System.getProperty("os.name").toLowerCase();
        if (!OS.contains("windows")) {
            filePath = basePath + filePath;
        }
        Map<String, String> param = new HashMap<>();
        param.put("file_path", filePath);
        param.put("charset", charset);
        param.put("start_line", startLine);
        param.put("read_line", readLine);
        return param;
    }

    private List<Okv> getReadLineResult(String data) {
        return JSON.parseObject(data)
                .entrySet()
                .stream()
                .sorted((x, y) -> Integer.compare(Integer.parseInt(x.getKey()), Integer.parseInt(y.getKey())))
                .map(t -> Okv.by("line", t.getKey()).set("data", t.getValue()))
                .collect(Collectors.toList());
    }

    public Object readLines(String serverId, String basePath, String filePath, String charset, String startLine, String readLine) {
        try {
            String data = post(getUrl(serverId, "/api/log/manege/read/lines"), getParaMap(basePath, filePath, charset, startLine, readLine));
            List<Okv> collect = getReadLineResult(data);
            return JSON.toJSON(collect);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public Object basePath(String serverId) {
        return post(getUrl(serverId, "/api/log/manege/base/path"), new HashMap<>());
    }

    private String post(String url, Map<String, String> param) {
        param.put("app_id", "5a9cf9dc8c21475f9a452d6955861b31");
        param.put("timestamp", String.valueOf(DateKit.getNowTimestamp()));
        String formatParam = RequestKit.formatParamMapToString(param) + "caad43148ac846fdac06ba8e504c78a9";
        param.put("sign", MD5Kit.encodeMD5Hex(formatParam));
        String post = HttpKit.post(url, param, null);
        JSONObject resp;
        try {
            resp = JSONObject.parseObject(post);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
        if ("200".equals(resp.getString("status"))) {
            return resp.getString("data");
        }
        throw new BaseException(resp.getString("message"));
    }

}

